<!-- 密码策略配置页面-->
<!--created by yuyupeng-->
<!--2023/04/12-->
<template>
  <div class="list-card-container">
    <a-card class="general-card">
      <a-page-header
        style="border: 0px solid rgb(235, 237, 240)"
        :show-back="false"
      >
        <template #title> {{ currentStrategyName }}密码策略全局配置 </template>
      </a-page-header>
      <a-tabs
        :active-key="currentStrategyId"
        @tab-click="currentStrategyIdChange"
      >
        <a-tab-pane
          v-for="item of tbData"
          :key="item.id"
          :title="item.strategyName"
        >
        </a-tab-pane>
      </a-tabs>
      <a-form
        v-if="tbData.length > 0"
        ref="formObject"
        :model="currentForm"
        :rules="rules"
        :label-col-props="{ span: 3 }"
        @submit="handleSubmit"
      >
        <a-row>
          <a-form-item field="strategyName" label="策略模板名称">
            <a-input
              v-model="currentForm.strategyName"
              class="form-item-style"
            />
          </a-form-item>
        </a-row>
        <a-row>
          <a-form-item
            field="minLength"
            label="最短密码长度"
            extra="请输入6~32之间的整数"
          >
            <a-input-number
              v-model="currentForm.minLength"
              :min="6"
              :max="32"
              :precision="0"
              class="form-item-style"
              @change="changeCurrentMinmaxLength"
            />个字符
          </a-form-item>
        </a-row>
        <a-row>
          <a-form-item
            field="maxLength"
            label="最长密码长度"
            extra="请输入6~32之间的整数"
          >
            <a-input-number
              v-model="currentForm.maxLength"
              :min="currentMinmaxLength"
              :max="32"
              :precision="0"
              class="form-item-style"
            />个字符
          </a-form-item>
        </a-row>
        <a-row>
          <a-form-item field="passwordComplexity" label="密码复杂度">
            <a-checkbox-group v-model="passwordComplexity">
              <a-checkbox value="mustCapital">大写字母</a-checkbox>
              <a-checkbox value="mustLowercase">小写字母</a-checkbox>
              <a-checkbox value="mustSymbols">特殊符号</a-checkbox>
              <a-checkbox value="mustNumber">数字</a-checkbox>
            </a-checkbox-group>
          </a-form-item>
        </a-row>
        <a-row>
          <a-form-item
            field="expireDays"
            label="密码更新周期"
            extra="限制更改密码的周期，请输入0~365之间的整数，0表示不限制"
          >
            <a-input-number
              v-model="currentForm.expireDays"
              :min="0"
              :max="365"
              :precision="0"
              class="form-item-style"
            />天
          </a-form-item>
        </a-row>
        <a-row>
          <a-form-item
            field="historyPasswordCounts"
            label="密码历史限制"
            extra="限制新密码与历史密码的重复。请输入0~10之间的整数，0表示不限制"
          >
            <a-input-number
              v-model="currentForm.historyPasswordCounts"
              :min="0"
              :max="10"
              :precision="0"
              class="form-item-style"
            />次
          </a-form-item>
        </a-row>
        <a-row>
          <a-form-item
            label="锁定规则"
            :content-flex="false"
            :merge-props="false"
          >
            <a-row :gutter="8">
              <a-col :span="10">
                <a-form-item
                  field="maxErrorCounts"
                  :validate-trigger="['change', 'input']"
                  :rules="[{ required: true, message: '请输入' }]"
                  hide-label
                >
                  密码错误
                  <a-input-number
                    v-model="currentForm.maxErrorCounts"
                    :min="1"
                    :max="10"
                    :precision="0"
                    style="margin-left: 5px"
                    class="form-item-style"
                  />
                  次后，锁定
                </a-form-item>
              </a-col>
              <a-col :span="10">
                <a-form-item
                  field="lockedMinutes"
                  :validate-trigger="['change', 'input']"
                  :rules="[{ required: true, message: '请输入' }]"
                  hide-label
                >
                  <a-input-number
                    v-model="currentForm.lockedMinutes"
                    :min="0"
                    :max="10080"
                    :precision="0"
                    class="form-item-style"
                  />分钟
                </a-form-item>
              </a-col>
            </a-row>
          </a-form-item>
        </a-row>
        <a-form-item>
          <a-button type="primary" html-type="submit" style="width: 180px">
            提交更改
          </a-button>
        </a-form-item>
      </a-form>
      <a-empty v-else>暂无密码策略配置模板！</a-empty>
    </a-card>
    <!-- 新增密码策略模板Modal -->
    <a-modal
      :visible="addModalVisible"
      :width="800"
      title="新增密码策略模板"
      :mask-closable="false"
      @ok="submitAddPasswordStrategy"
      @cancel="cancelAddPasswordStrategy"
    >
      <a-form
        ref="addFormObject"
        :model="addForm"
        :rules="rules"
        :label-col-props="{ span: 4 }"
      >
        <a-row>
          <a-form-item field="strategyName" label="策略模板名称">
            <a-input v-model="addForm.strategyName" class="form-item-style" />
          </a-form-item>
        </a-row>
        <a-row>
          <a-form-item
            field="minLength"
            label="最短密码长度"
            extra="请输入6~32之间的整数"
          >
            <a-input-number
              v-model="addForm.minLength"
              :min="6"
              :max="32"
              :precision="0"
              class="form-item-style"
              @change="changeCurrentMinmaxLengthForAddModal"
            />个字符
          </a-form-item>
        </a-row>
        <a-row>
          <a-form-item
            field="maxLength"
            label="最长密码长度"
            extra="请输入6~32之间的整数"
          >
            <a-input-number
              v-model="addForm.maxLength"
              :min="currentMinmaxLengthForAddModal"
              :max="32"
              :precision="0"
              class="form-item-style"
            />个字符
          </a-form-item>
        </a-row>
        <a-row>
          <a-form-item field="passwordComplexity" label="密码复杂度">
            <a-checkbox-group v-model="passwordComplexityForAddModal">
              <a-checkbox value="mustCapital">大写字母</a-checkbox>
              <a-checkbox value="mustLowercase">小写字母</a-checkbox>
              <a-checkbox value="mustSymbols">特殊符号</a-checkbox>
              <a-checkbox value="mustNumber">数字</a-checkbox>
            </a-checkbox-group>
          </a-form-item>
        </a-row>
        <a-row>
          <a-form-item
            field="expireDays"
            label="密码更新周期"
            extra="限制更改密码的周期，请输入0~365之间的整数，0表示不限制"
          >
            <a-input-number
              v-model="addForm.expireDays"
              :min="0"
              :max="365"
              :precision="0"
              class="form-item-style"
            />天
          </a-form-item>
        </a-row>
        <a-row>
          <a-form-item
            field="historyPasswordCounts"
            label="密码历史限制"
            extra="限制新密码与历史密码的重复。请输入0~10之间的整数，0表示不限制"
          >
            <a-input-number
              v-model="addForm.historyPasswordCounts"
              :min="0"
              :max="10"
              :precision="0"
              class="form-item-style"
            />次
          </a-form-item>
        </a-row>
        <a-row>
          <a-form-item
            label="锁定规则"
            :content-flex="false"
            :merge-props="false"
          >
            <a-row :gutter="8">
              <a-col :span="12">
                <a-form-item
                  field="maxErrorCounts"
                  :validate-trigger="['change', 'input']"
                  :rules="[{ required: true, message: '请输入' }]"
                  hide-label
                >
                  密码错误
                  <a-input-number
                    v-model="addForm.maxErrorCounts"
                    :min="1"
                    :max="10"
                    :precision="0"
                    style="margin-left: 5px"
                    class="form-item-style"
                  />
                  次后，锁定
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item
                  field="lockedMinutes"
                  :validate-trigger="['change', 'input']"
                  :rules="[{ required: true, message: '请输入' }]"
                  hide-label
                >
                  <a-input-number
                    v-model="addForm.lockedMinutes"
                    :min="0"
                    :max="10080"
                    :precision="0"
                    class="form-item-style"
                  />分钟
                </a-form-item>
              </a-col>
            </a-row>
          </a-form-item>
        </a-row>
      </a-form>
    </a-modal>
    <!-- 删除密码策略模板确认框 -->
    <a-modal
      :visible="deleteModalVisible"
      @ok="submitDeletePasswordStrategy"
      @cancel="cancelDeletePasswordStrategy"
    >
      <template #title>
        <icon-exclamation-circle-fill
          style="color: #fde800"
          size="24"
        />确定删除{{ deleteStrategyName }}密码策略配置吗？
      </template>
      <div>此操作将导致使用该密码策略配置的用户密码操作不受约束</div>
    </a-modal>
  </div>
</template>

<script lang="ts" setup>
  import {
    queryPasswordStrategyRecordList,
    editPasswordStrategyRecord,
    deletePasswordStrategyRecords,
    addPasswordStrategyRecord,
  } from '@/api/system/passwordStrategy';
  import { onMounted, ref } from 'vue';
  import { Notification } from '@arco-design/web-vue';
  import {
    PasswordStrategyParams,
    PasswordStrategyRecord,
  } from '@/api/system/model/passwordStrategyModel';

  /**
   * data
   */
  const currentForm = ref<PasswordStrategyRecord>({
    // 新增的密码策略配置模板表单
    id: '1', // id
    isEnabled: false, // 是否启用
    strategyName: '',
    minLength: 1, // 最短密码长度
    maxLength: 1, // 最长密码长度
    mustCapital: false, // 大写字母
    mustLowercase: false, // 小写字母
    mustSymbols: false, // 特殊符号
    mustNumber: false, // 数字
    expireDays: 1, // 密码更新周期
    maxErrorCounts: 1, // 密码错误几次会锁定
    lockedMinutes: 1, // 锁定时长(分钟)
    historyPasswordCounts: 1, // 密码历史限制
  });
  const addForm = ref<PasswordStrategyRecord>({
    // 新增的密码策略配置模板表单
    // id: undefined, // id
    isEnabled: undefined, // 是否启用
    strategyName: undefined,
    minLength: undefined, // 最短密码长度
    maxLength: undefined, // 最长密码长度
    mustCapital: undefined, // 大写字母
    mustLowercase: undefined, // 小写字母
    mustSymbols: undefined, // 特殊符号
    mustNumber: undefined, // 数字
    expireDays: undefined, // 密码更新周期
    maxErrorCounts: undefined, // 密码错误几次会锁定
    lockedMinutes: undefined, // 锁定时长(分钟)
    historyPasswordCounts: undefined, // 密码历史限制
  });
  const tbData = ref<PasswordStrategyRecord[]>([]);
  const formObject = ref<any>();
  const addFormObject = ref<any>();
  const currentMinmaxLength = ref<number>(6); // 当前最长密码长度的合法范围的下限，它等于最短密码长度的上限
  const currentMinmaxLengthForAddModal = ref<number>(6); // 当前最长密码长度的合法范围的下限，它等于最短密码长度的上限
  const passwordComplexity = ref<string[]>([]); // 密码复杂度复选框组绑定的值
  const passwordComplexityForAddModal = ref<string[]>([]); // 新增对话框表单中的密码复杂度复选框组绑定的值
  // 密码策略表单项校验配置
  const rules = ref({
    strategyName: [{ required: true, message: '请输入策略模板名称' }],
    minLength: [{ required: true, message: '请输入最短密码长度' }],
    maxLength: [{ required: true, message: '请输入最长密码长度' }],
    expireDays: [{ required: true, message: '请输入密码更新周期' }],
    maxErrorCounts: [{ required: true, message: '请输入密码错误几次会锁定' }],
    lockedMinutes: [{ required: true, message: '请输入锁定时长(分钟)' }],
    historyPasswordCounts: [{ required: true, message: '请输入密码历史限制' }],
  });
  const currentStrategyId = ref<string>(); // 当前所处的密码策略模板id
  const currentStrategyName = ref<string>(); // 当前所处的密码策略模板名称
  const deleteStrategyId = ref<string>(); // 想要删除的密码策略模板id
  const deleteStrategyName = ref<string>(); // 想要删除的密码策略模板名称
  const addModalVisible = ref<boolean>(false); // 控制新增密码策略模板对话框是否显示
  const deleteModalVisible = ref<boolean>(false); // 控制删除密码策略模板对话框是否显示
  /**
   * fun
   */
  /**
   * @description 获取密码策略
   */
  const getCurrentPasswordStrategy = async (reqdata: any = {}) => {
    const params: PasswordStrategyParams = {
      page: 1,
      limit: 10,
      ...reqdata,
    };
    try {
      const { data } = await queryPasswordStrategyRecordList(params);
      if (!params.id) {
        // 如果不存在id属性，则说明是全查，用tbData记录下所有的密码策略模板
        tbData.value = data.list;
      }
      if (data.total > 0) {
        currentForm.value = data.list[0] as PasswordStrategyRecord;
        currentForm.value.expireDays = Number(currentForm.value.expireDays); // 转成Number，要不然前端渲染不出来
        currentForm.value.lockedMinutes = Number(
          currentForm.value.lockedMinutes
        ); // 转成Number，要不然前端渲染不出来
        currentStrategyId.value = currentForm.value.id;
        currentStrategyName.value = currentForm.value.strategyName;
        passwordComplexity.value = [];
        if (currentForm.value.mustCapital === true) {
          // 大写字母
          passwordComplexity.value.push('mustCapital');
        }
        if (currentForm.value.mustLowercase === true) {
          // 小写字母
          passwordComplexity.value.push('mustLowercase');
        }
        if (currentForm.value.mustSymbols === true) {
          // 特殊字符
          passwordComplexity.value.push('mustSymbols');
        }
        if (currentForm.value.mustNumber === true) {
          // 数字
          passwordComplexity.value.push('mustNumber');
        }
      }
    } catch (error) {
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      Notification.error({
        content: `出现异常！${error}`,
        closable: true,
      });
    }
  };
  /**
   * @description 更新密码策略
   */
  const handleSubmit = async ({ errors }: { errors: any }) => {
    if (!errors) {
      // console.log('校验通过。。。');
      const passwordComplexityString = passwordComplexity.value.toString();
      currentForm.value.mustCapital =
        passwordComplexityString.indexOf('mustCapital') > -1; // 大写字母
      currentForm.value.mustLowercase =
        passwordComplexityString.indexOf('mustLowercase') > -1; // 小写字母
      currentForm.value.mustSymbols =
        passwordComplexityString.indexOf('mustSymbols') > -1; // 特殊符号
      currentForm.value.mustNumber =
        passwordComplexityString.indexOf('mustNumber') > -1; // 数字
      try {
        const res = (await editPasswordStrategyRecord(
          currentForm.value
        )) as any;
        if (res.code === 200) {
          Notification.success({
            content: '修改密码策略成功！',
          });
        } else {
          Notification.error({
            title: '修改密码策略失败！',
            content: res.message,
          });
        }
      } catch (error) {
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        Notification.error({
          content: `出现异常！${error}`,
          closable: true,
        });
      }
    }
  };
  /**
   * @description 修改当前最长密码长度的合法范围的下限
   * @param value
   */
  const changeCurrentMinmaxLength = (value: number) => {
    currentMinmaxLength.value = value;
  };
  /**
   * @description 修改当前最长密码长度的合法范围的下限 新建对话框专用
   * @param value
   */
  const changeCurrentMinmaxLengthForAddModal = (value: number) => {
    currentMinmaxLengthForAddModal.value = value;
  };
  /**
   * @description 标签页变化触发
   * @param key
   */
  const currentStrategyIdChange = (key: string) => {
    getCurrentPasswordStrategy({ id: key });
  };
  /**
   * @description 新增标签页触发
   */
  /* const addPasswordStrategy = () => {
    addModalVisible.value = true;
  }; */
  /**
   * @description 提交新增密码策略模板操作
   */
  const submitAddPasswordStrategy = async () => {
    addFormObject.value.validate(async (errors: any) => {
      if (!errors) {
        // 校验成功
        const passwordComplexityString =
          passwordComplexityForAddModal.value.toString();
        addForm.value.mustCapital =
          passwordComplexityString.indexOf('mustCapital') > -1; // 大写字母
        addForm.value.mustLowercase =
          passwordComplexityString.indexOf('mustLowercase') > -1; // 小写字母
        addForm.value.mustSymbols =
          passwordComplexityString.indexOf('mustSymbols') > -1; // 特殊符号
        addForm.value.mustNumber =
          passwordComplexityString.indexOf('mustNumber') > -1; // 数字
        try {
          const res = (await addPasswordStrategyRecord(addForm.value)) as any;
          if (res.code === 200) {
            Notification.success({
              content: '保存成功！',
            });
          } else {
            Notification.error({
              title: '保存失败！',
              content: res.message,
            });
          }
        } catch (error) {
          // eslint-disable-next-line @typescript-eslint/no-unused-vars
          Notification.error({
            content: `出现异常！${error}`,
            closable: true,
          });
        } finally {
          getCurrentPasswordStrategy();
        }
        cancelAddPasswordStrategy();
      }
    });
  };
  /**
   * @description 取消新增密码策略模板操作
   */
  const cancelAddPasswordStrategy = () => {
    addModalVisible.value = false;
    addFormObject.value.resetFields(); // 关闭对话框的时候重置一下表单
    passwordComplexityForAddModal.value = []; //  关闭对话框的时候重置一下passwordComplexityForAddModal
  };
  /**
   * @description 删除页签触发
   * @param key
   */
  /* const deletePasswordStrategy = (key: string) => {
    deleteStrategyId.value = key;
    deleteStrategyName.value = tbData.value.filter(
      (item) => item.id === key
    )[0].strategyName;
    deleteModalVisible.value = true;
  }; */
  /**
   * @description 提交删除密码策略模板操作
   */
  const submitDeletePasswordStrategy = async () => {
    const reqdata = [];
    reqdata.push(deleteStrategyId.value);
    try {
      const res = (await deletePasswordStrategyRecords(reqdata)) as any;
      if (res.code === 200) {
        Notification.success({
          content: '删除成功！',
        });
      } else {
        Notification.error({
          title: '删除失败！',
          content: res.message,
        });
      }
      deleteModalVisible.value = false;
    } catch (error) {
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      Notification.error({
        content: `出现异常！${error}`,
        closable: true,
      });
    } finally {
      getCurrentPasswordStrategy();
    }
  };
  /**
   * @description 取消删除密码策略模板操作
   */
  const cancelDeletePasswordStrategy = () => {
    deleteModalVisible.value = false;
  };
  /**
   * onMounted
   */
  onMounted(() => {
    getCurrentPasswordStrategy();
  });
</script>

<style lang="less" scoped>
  .list-card-container {
    padding: 20px;
    // background-color: var(--color-bg-1);
    border-radius: var(--border-radius-default);
  }
  .form-item-style {
    width: 50%;
  }
</style>
